/* Copyright 2001,2002,2003 NAH6 BV
 * All Rights Reserved
 *
 *  $Header: /var/lib/cvs/secphone/ui/phone/RilClass.cpp,v 1.17 2003/11/21 16:12:58 itsme Exp $
 *
 *
 * this module handles call state determination for the volumemanager
 * and requests signal strength.
 *
 */

#include <windows.h>
#include "CPhone.h"
#include "CPhoneDlg.h"

#include "debug.h"
#include "ril.h"
#include "RilClass.h"
#include "VolumeManager.h"

#include "UDCLicenseHandler.h"

void HandleCallControlRing(RILRINGINFO* ri, DWORD cbdata);
void HandleCallControlConnect(RILCONNECTINFO* ci, DWORD cbdata);
void HandleCallControlDisconnect(DWORD* d, DWORD cbdata);

RilClass::RilClass()
{
    m_hRil= 0;
}
RilClass::~RilClass()
{
    close();
}
bool RilClass::open(DWORD dwIndex)
{
#ifdef _HAVE_RIL
    HRESULT res= RIL_Initialize(dwIndex, &ResultProc, &NotifyProc, -1, (DWORD)this, &m_hRil);
    if (res)
    {
        error("RIL_Initialize: %08lx\n", res);
        return false;
    }
#endif
    return true;
}
bool RilClass::close()
{
    bool bRes= true;
#ifdef _HAVE_RIL
    if (m_hRil)
    {
        HRESULT res= RIL_Deinitialize(m_hRil);
        if (res)
        {
            error("RIL_Deinitialize: %08lx\n", res);
            bRes= false;
        }
        m_hRil= 0;
    }
#endif
    return bRes;
}

void RilClass::ResultProc(DWORD dwCode, HRESULT hrCmdID, const void *lpData, DWORD cbdata, DWORD dwParam)
{
    ((RilClass*)dwParam)->HandleResult(dwCode, hrCmdID, lpData, cbdata);
}
void RilClass::NotifyProc(DWORD dwCode, const void *lpData, DWORD cbdata, DWORD dwParam)
{
    ((RilClass*)dwParam)->HandleNotify(dwCode, lpData, cbdata);
}
void RilClass::HandleResult(DWORD dwCode, HRESULT hrCmdID, const void *lpData, DWORD cbdata)
{
    DWORD dwRilError= 0;

    if (dwCode==RIL_RESULT_ERROR) {
        if (cbdata!=sizeof(DWORD)) {
            debug("ril-error - missing error code\n");
            return;
        }
        else {
            dwRilError= *(DWORD*)lpData;
        }
    }
    //  find command the requested this result.

    if (hrCmdID==m_hrImeiRequest) {
        m_hrImeiRequest= 0;
        if (dwCode==RIL_RESULT_OK) {
            if (cbdata!=sizeof(RILEQUIPMENTINFO))
                return;
            HandleImeiAnswer((RILEQUIPMENTINFO*)lpData);
        }
    }
    else if (hrCmdID==m_hrSignalQualityRequest) {
        m_hrSignalQualityRequest= 0;

        if (dwCode==RIL_RESULT_OK) {
            if (cbdata!=sizeof(RILSIGNALQUALITY))
                return;
            HandleSignalQualityAnswer((RILSIGNALQUALITY *)lpData);
        }
        else {
            HandleSignalQualityError(dwRilError);
        }
    }
    else {
        debug("ril::HandleResult - discarding result, expecting imei=%08lx, signal=%08lx\n",
            m_hrImeiRequest, m_hrSignalQualityRequest);
    }
}
void RilClass::HandleSignalQualityAnswer(RILSIGNALQUALITY *sq)
{
#if 0
    debug("HandleSignalQualityAnswer sig=%d min=%d max=%d low=%d high=%d\n",
        sq->nSignalStrength,
        sq->nMinSignalStrength, sq->nMaxSignalStrength, 
        sq->nLowSignalStrength, sq->nHighSignalStrength);
#endif

    if (sq->nSignalStrength==-1)
        theApp.m_dlg->SetSignalNone("Searching for signal", "please wait");
    else
        theApp.m_dlg->SetSignalQuality(sq->nSignalStrength, sq->nLowSignalStrength, sq->nHighSignalStrength);
}
void RilClass::HandleSignalQualityError(DWORD dwRilError)
{
    theApp.m_dlg->SetSignalNone("GSM is unavailable", "");
}

void RilClass::HandleImeiAnswer(RILEQUIPMENTINFO* info)
{
    theApp.m_lic->VerifyROMLicense(std::string(info->szSerialNumber));
}

void HandleCallControlRing(RILRINGINFO* ri, DWORD cbdata)
{
    if (ri->dwCallType==RIL_CALLTYPE_VOICE)
        theApp.m_volmgr->SignalRinging();
}
void HandleCallControlConnect(RILCONNECTINFO* ci, DWORD cbdata)
{
    if (ci->dwCallType==RIL_CALLTYPE_VOICE)
        theApp.m_volmgr->SignalVoiceConnect();
}

void HandleCallControlDisconnect(DWORD* d, DWORD cbdata)
{
    theApp.m_volmgr->SignalRILDisconnect();
}

void RilClass::HandleNotify(DWORD dwCode, const void *lpData, DWORD cbdata)
{
    switch(dwCode) {
        case RIL_NOTIFY_RING: HandleCallControlRing((RILRINGINFO*)lpData, cbdata); break;
        case RIL_NOTIFY_CONNECT: HandleCallControlConnect((RILCONNECTINFO*)lpData, cbdata); break;
        case RIL_NOTIFY_DISCONNECT: HandleCallControlDisconnect((DWORD*)lpData, cbdata); break;
    }
}

bool RilClass::RequestSignalQuality()
{
#ifdef _HAVE_RIL
    if (m_hRil==NULL)
    {
        debug("ERROR: ril not initialized\n");
        return false;
    }
    if (m_hrSignalQualityRequest)
    {
        debug("RequestSignalQuality: still busy\n");
        return true;
    }
    m_hrSignalQualityRequest= RIL_GetSignalQuality(m_hRil);
    if (IS_ERROR(m_hrSignalQualityRequest))
    {
        error(m_hrSignalQualityRequest, "RIL_GetSignalQuality");
        m_hrSignalQualityRequest= 0;
        return false;
    }
#endif
    return true;
}


bool RilClass::RequestIMEI()
{
#ifdef _HAVE_RIL
    if (m_hrImeiRequest)
    {
        debug("RequestIMEI: still busy\n");
        return true;
    }
    m_hrImeiRequest= RIL_GetEquipmentInfo(m_hRil);
    if (IS_ERROR(m_hrImeiRequest))
    {
        error(m_hrImeiRequest, "RIL_GetEquipmentInfo");
        m_hrImeiRequest= 0;
        return false;
    }
#endif
    return true;
}

